/*
    Android UIML

	Copyright (C) 2010  Bram Goffings (bramgoffings@gmail.com)

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public License
	as published by the Free Software Foundation; either version 2.1
	of	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

package uiml.android.rendering;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;

import uiml.android.RenderTools.LayoutUtils;
import uiml.android.RenderTools.ViewGroupUtils;
import uiml.android.main.AndroidUiml;
import android.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.InputFilter;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class AndroidTypeDecoder extends CustomTypeDecoder{

	/**
	 * 
	 */
	public AndroidTypeDecoder() {
		super();
		initiliase();
	}
	
	/**
	 * 
	 */
	public void initiliase() {
		// Type to function
		typeToFunction.put("orientation", "decodeOrientation");
		typeToFunction.put("label", "decodeString");
		typeToFunction.put("textOff", "decodeString");
		typeToFunction.put("textOn", "decodeString");
		typeToFunction.put("id", "decodeIdentifier");
		typeToFunction.put("adapter", "decodeAdapter");
		typeToFunction.put("image", "decodeImage");
		typeToFunction.put("gravity", "decodeGravity");
		
		// Non reflection methods
		nonReflectionMethods.put(new CustomTypeDecoderDuo("width", "setMethod"), "setLayoutWidth");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("height", "setMethod"), "setLayoutHeight");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("backgroundColor", "setMethod"), "setBackgroundColor");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("margins", "setMethod"), "setLayoutMargins");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("id", "setMethod"), "decodeIdentifier");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("tab", "setMethod"), "addTab");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("scaleType","setMethod"), "decodeScaleType");
		nonReflectionMethods.put(new CustomTypeDecoderDuo("maxLengthFilter","setMethod"), "decodeMaxLengthFilter");
	}
	
	// Methods that return the desired object
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public Object decodeOrientation(String value) {
		
		if(value.equalsIgnoreCase("horizontal") || value.equals("0"))
			return new Integer(0);
		else if(value.equalsIgnoreCase("vertical") || value.equals("1"))
			return new Integer(1);
		
		// Default horizontal
		return 0;
	}
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public Object decodeGravity(String value) {
		
		if(value.equalsIgnoreCase("left"))
			return Gravity.LEFT;
		else if(value.equalsIgnoreCase("right"))
			return Gravity.RIGHT;
		else if(value.equalsIgnoreCase("center"))
			return Gravity.CENTER;
		else if(value.equalsIgnoreCase("center_horizontal"))
			return Gravity.CENTER_HORIZONTAL;
		else if(value.equalsIgnoreCase("center_vertical"))
			return Gravity.CENTER_VERTICAL;
		else if(value.equalsIgnoreCase("top"))
			return Gravity.TOP;
		else if(value.equalsIgnoreCase("bottom"))
			return Gravity.BOTTOM;
		else if(value.equalsIgnoreCase("fill"))
			return Gravity.FILL;
		else if(value.equalsIgnoreCase("fill_horizontal"))
			return Gravity.FILL_HORIZONTAL;
		else if(value.equalsIgnoreCase("fill_vertical"))
			return Gravity.FILL_VERTICAL;
		else
			return Gravity.NO_GRAVITY;
	}
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public Object decodeAdapter(String value) {
		
		String[] input = value.split(";");
		
		//
		if(input[0].equals("simple_spinner_dropdown_item")) {
			
			Vector<String> values = new Vector<String>();
			
			for(int i=1; i<input.length; ++i)
				values.add(input[i]);
			
			return new ArrayAdapter(AndroidUiml.me, R.layout.simple_dropdown_item_1line, values.toArray());	
		}
		
		return 0;
	}
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public Object decodeImage(String value) {
		
		Bitmap bmImg = null;
		URL myFileUrl =null; 
		
		try {
			myFileUrl= new URL(value);
			HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bmImg = BitmapFactory.decodeStream(is);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return bmImg;	
	}
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public Object decodeString(String value) {
		return (Object) value;
	}
	
	
	// Methods which call functions without using any form of reflection
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public void decodeIdentifier(View view, String value) {
		
		if(value.equals("android.R.id.tabs"))
			view.setId(android.R.id.tabs);
		else if(value.equals("android.R.id.tabcontent"))
			view.setId(android.R.id.tabcontent);
		else
			view.setId(new Integer(value));
	}
	
	/**
	 * 
	 * @param view
	 * @param value
	 */
	public void setLayoutWidth(View view, String value) {	
		
		if(value.equalsIgnoreCase("fill_parent"))
			LayoutUtils.setLayoutWidth(view, ViewGroup.LayoutParams.FILL_PARENT);
		else if(value.equalsIgnoreCase("wrap_content"))
			LayoutUtils.setLayoutWidth(view, ViewGroup.LayoutParams.WRAP_CONTENT);
		else {				
			int width = 0;
			
			if(value.contains("dip")) {
				
				value = value.substring(0, value.length()-3);
				width = new Integer(value);
				float density = AndroidUiml.me.getResources().getDisplayMetrics().density;
				width = (int) (width * density);
			}
			else
				width = new Integer(value);
			
			LayoutUtils.setLayoutWidth(view, width);
		}
	}
	
	/**
	 * 
	 * @param view
	 * @param value
	 */
	public void setLayoutHeight(View view, String value) {	
		
		if(value.equalsIgnoreCase("fill_parent"))
			LayoutUtils.setLayoutHeight(view, -1);
		else if (value.equalsIgnoreCase("wrap_content"))
			LayoutUtils.setLayoutHeight(view, -2);
		else {
					
			int height = 0;
			
			if(value.contains("dip")) {
				
				value = value.substring(0, value.length()-3);
				height = new Integer(value);
				float density = AndroidUiml.me.getResources().getDisplayMetrics().density;
				height = (int) (height * density);
			}
			else
				height = new Integer(value);
			
			LayoutUtils.setLayoutHeight(view, height);
		}
	}
	
	/**
	 * 
	 * @param value
	 */
	public void setLayoutMargins(View view, String value) {	
		
		String[] values = value.split(",");
		LayoutUtils.setLayoutMargins(view, new Integer(values[0]), new Integer(values[1]), new Integer(values[2]), new Integer(values[3]));
	}
	
	/**
	 * 
	 * @param value
	 */
	public void setBackgroundColor(View view, String value) {	
		
		try {
			if(value.equals("0xFF00FF00"))
				view.setBackgroundColor(0xFF00FF00);
			else if(value.equals("0xFFFFFFFF"))
				view.setBackgroundColor(0xFFFFFFFF);
			else if(value.equals("white"))
				view.setBackgroundColor(0xFFFFFFFF);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @param value
	 */
	public void addTab(View view, String value) {	
		
		String[] values = value.split(",");
		ViewGroupUtils.addTab(view, values[0], values[1], new Integer(values[2]));
	}
	
	/**
	 * 
	 * @param value
	 */
	public void decodeScaleType(View view, String value) {
		
		if(value.equalsIgnoreCase("center_crop"))
			((ImageView)view).setScaleType(ImageView.ScaleType.CENTER_CROP);
		else if(value.equalsIgnoreCase("center_inside"))
			((ImageView)view).setScaleType(ImageView.ScaleType.CENTER_INSIDE);
		else
			((ImageView)view).setScaleType(ImageView.ScaleType.FIT_CENTER);	
	}
	
	/**
	 * 
	 * @param value
	 */
	public void decodeMaxLengthFilter(View view, String value) {
		
		int maxLength = new Integer(value);
		
		InputFilter[] FilterArray = new InputFilter[1];
		FilterArray[0] = new InputFilter.LengthFilter(maxLength);
		((TextView)view).setFilters(FilterArray);
	}
	
}
